//
//  LBThreeInputFilter.mm
//  OpenGLGame
//
//  Created by Nguyen Cong Huy on 12/9/12.
//  Copyright (c) 2012 UIT. All rights reserved.
//

#include <iostream>
#include "LBThreeInputFilter.h"
#include "LBGraphics.h"
#include "LBTexture.h"
#include "LBFramebuffer.h"
#include "Matrix.h"

char threeInputVerShaderStr[] = ""

"attribute vec4 position;"
"attribute vec4 texCoor;"
"attribute vec4 texCoor2;"
"attribute vec4 texCoor3;"
"uniform mat4 mWorld;"
"uniform mat4 mProjection;"

"varying vec2 vtexCoor;"
"varying vec2 vtexCoor2;"
"varying vec2 vtexCoor3;"
"varying vec4 vposition;"

"void main()"
"{"
"    gl_Position = mProjection * mWorld * position;"
"    vtexCoor = texCoor.xy;"
"    vtexCoor2 = texCoor2.xy;"
"    vtexCoor3 = texCoor3.xy;"
"    vposition = gl_Position;"
"}";

char threeInputFragShaderStr[] = ""
"precision highp float;"

"varying highp vec2 vtexCoor;"
"varying highp vec2 vtexCoor2;"
"varying highp vec2 vtexCoor3;"

"uniform sampler2D texture;"
"uniform sampler2D texture2; "
"uniform sampler2D texture3; "

"void main()"
"{"
"    lowp vec4 textureColor = texture2D(texture, vtexCoor);"
"    lowp vec4 texture2Color = texture2D(texture2, vtexCoor2);"
"    lowp vec4 texture3Color = texture2D(texture3, vtexCoor3);"
"    gl_FragColor = textureColor;"
"}";

LBThreeInputFilter::LBThreeInputFilter(){
    texture2 = 0;
    texture3 = 0;
}

void LBThreeInputFilter::init(char* vShaderStr, char* fShaderStr){
    if(vShaderStr == 0 && fShaderStr == 0)
        LBFilter::init(threeInputVerShaderStr, threeInputFragShaderStr);
    if(vShaderStr == 0 && fShaderStr != 0)
        LBFilter::init(threeInputVerShaderStr, fShaderStr);
    else if(vShaderStr != 0 && fShaderStr == 0)
        LBFilter::init(vShaderStr, threeInputFragShaderStr);
    else LBFilter::init(vShaderStr, fShaderStr);
    texture2Uniform = program->uniformIndex("texture2");
    texCoor2Attribute = program->attributeIndex("texCoor2");
    texture3Uniform = program->uniformIndex("texture3");
    texCoor3Attribute = program->attributeIndex("texCoor3");
}

void LBThreeInputFilter::renderTexture(int x, int y, float scaleX, float scaleY){
    LBGraphics* g = LBGraphics::getInstance();
    texture->setLocationAndScale(x, y, scaleX, scaleY);
    texture->setAngle(0);
    if(texture2 != 0){
        texture2->setLocationAndScale(x, y, scaleX, scaleY);
        texture2->setAngle(0);
    }
    if(texture3 != 0){
        texture3->setLocationAndScale(x, y, scaleX, scaleY);
        texture3->setAngle(0);
    }
    texture->calculateMatrix();
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture->getTexId());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    glUniform1i(textureUniform, 0);
    glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, texture->getImageVertices());
    glVertexAttribPointer(texCoorAttribute, 2, GL_FLOAT, GL_FALSE, 0, texture->getTexCoors());
    glUniformMatrix4fv(mWorldUniform, 1, GL_FALSE, &(texture->getWorldMatrix()->m[0][0]));
    glUniformMatrix4fv(mProjectionUniform, 1, GL_FALSE, &(g->getProjectionMatrix()->m[0][0]));
    
    glActiveTexture(GL_TEXTURE1);
    if(texture2 != 0){
        glBindTexture(GL_TEXTURE_2D, texture2->getTexId());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glUniform1i(texture2Uniform, 1);
        glVertexAttribPointer(texCoor2Attribute, 2, GL_FLOAT, GL_FALSE, 0, texture2->getTexCoors());
    }
    
    glActiveTexture(GL_TEXTURE2);
    if(texture3 != 0){
        glBindTexture(GL_TEXTURE_2D, texture3->getTexId());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glUniform1i(texture3Uniform, 2);
        glVertexAttribPointer(texCoor3Attribute, 2, GL_FLOAT, GL_FALSE, 0, texture3->getTexCoors());
    }
    
    glEnableVertexAttribArray(positionAttribute);
    glEnableVertexAttribArray(texCoorAttribute);
    if(texture2 != 0)
        glEnableVertexAttribArray(texCoor2Attribute);
    if(texture3 != 0)
        glEnableVertexAttribArray(texCoor3Attribute);
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void LBThreeInputFilter::setTexture2(LBTexture* texture){
    texture2 = texture;
}

void LBThreeInputFilter::setTexture3(LBTexture* texture){
    texture3 = texture;
}